class RaidsController < ApplicationController
  before_filter :require_officer, :except => [ :index, :show, :create_signup ]

  def create
    @raid = Raid.new(params[:raid])
    if @raid.save
      redirect_to :action => :edit, :id => @raid.id
    end
  end

  def index
    @page_description = "Raids"
    @zones = Zone.find(:all)

    day_in_seconds = 60 * 60 * 24
    week_in_seconds = day_in_seconds * 7
    now = Time.now
    raid_day_start = Time.local(now.year, now.mon, now.day, 3)
    tomorrow = Time.at(raid_day_start.to_i + day_in_seconds)
    yesterday = Time.at(raid_day_start.to_i - day_in_seconds)
    @past_raids = Raid.paginate(:page => params[:page], :order => "date DESC", :conditions => [ "date < ?", now ])

    this_raid_week = raid_week(now)
    @raids_this_week = (0..6).collect { |day|
      [ this_raid_week[day], Raid.find(:all, :order => "date DESC", :conditions => [ "date > ? AND date < ?", this_raid_week[day], this_raid_week[day+1] ]) ]
    }
    next_raid_week = raid_week(Time.at(raid_day_start + week_in_seconds))
    @raids_next_week = (0..6).collect { |day|
      [ next_raid_week[day], Raid.find(:all, :order => "date DESC", :conditions => [ "date > ? AND date < ?", next_raid_week[day], next_raid_week[day+1] ]) ]
    }
  end

  def show
    if is_officer?
      redirect_to :action => :edit
    else
      @page_description = "Raids"
      @raid = Raid.find(params[:id])
      if is_member?
        @signed_up_for_this_raid = (not Signup.find(:first, :conditions => [ "character_id = ? AND raid_id = ?",
                                                                             @logged_in_user.character.id,
                                                                             @raid.id ]).nil?)
      else
        @signed_up_for_this_raid = false
      end
    end
  end

  def edit
    @page_description = "Edit raid"
    @raid = Raid.find(params[:id])
    @items = Item.find(:all, :order => "name")
    @characters = Character.find(:all, :order => "name")
    if @logged_in_user.character.nil?
      @signed_up_for_this_raid = false
    else
      @signed_up_for_this_raid = (not Signup.find(:first, :conditions => [ "character_id = ? AND raid_id = ?",
                                                                           @logged_in_user.character.id,
                                                                           @raid.id ]).nil?)
    end
    @all_roles = Role.find(:all)
  end

  def update
    if request.get?
      flash[:notice] = "Click the raid you wish to edit."
    else
      raid = Raid.find(params[:id])
      raid.update_attributes(params[:raid])
    end
    redirect_to :action => :index
  end

  def delete
    if request.get?
      flash[:notice] = "Select the raid you want to delete."
    else
      raid_was_deleted = false
      params.each_key { |k|
        if (k =~ /^deleteraid([[:digit:]]+)$/)
          Raid.destroy($1.to_i)
          raid_was_deleted = true
        end
      }
      if raid_was_deleted
        flash[:notice] = "Raids deleted."
      else
        flash[:notice] = "Select raids to delete."
      end
    end
    redirect_to :action => :index
  end

  def create_wanted_role
    params[:wanted_role][:raid_id] = params[:raid_id]
    wanted_roles = WantedRole.new(params[:wanted_role])
    if wanted_roles.save
      flash[:notice] = "New wanted list for roles created."
    end
    redirect_to :back
  end

  def delete_wanted_role
    wanted_roles_were_deleted = false
    params.each_key { |k|
      if (k =~ /^deletewantedrole([[:digit:]]+)$/)
        WantedRole.find($1.to_i).destroy
        wanted_roles_were_deleted = true
      end
    }
    if wanted_roles_were_deleted
      flash[:notice] = "Wanted roles were deleted."
    else
      flash[:notice] = "Select wanted roles to delete."
    end
    redirect_to :back
  end

  def create_signup
    unless still_got_time_to_signup_for_raid?(Raid.find(params[:raid_id]))
      flash[:notice] = "Too late to sign up for this raid."
      redirect_to :back
    end

    unless @logged_in_user.character.nil?
      signup = Signup.new({ :character_id => @logged_in_user.character.id, :raid_id => params[:raid_id] })
      if signup.save
        flash[:notice] = "You are now signed up for this raid."
      else
        flash[:notice] = "Failed to sign you up for this raid."
      end
    else
      flash[:notice] = "You can't sign up for a raid if you don't have a character."
    end
    redirect_to :back
  end

  def update_signups
    params.each_key { |k|
      if k =~ /^acceptsignup([[:digit:]]+)$/
        signup = Signup.find($1.to_i)
        signup.accepted = params[k][:accepted]
        if signup.save
          flash[:notice] = "Signups updated."
        else
          flash[:notice] = "Failed to update signups."
        end 
      end
    }
    redirect_to :back
  end

  def create_loot
    loot = Loot.new(params[:loot])
    loot.raid_id = params[:raid_id]
    if loot.save
      flash[:notice] = "#{loot.item.name} looted by #{loot.character.name}."
    else
      flash[:notice] = "Failed to add loot #{loot.item.name}."
    end
    expire_fragment("characters/dkp_table")
    redirect_to :action => :edit, :id => loot.raid.id
  end

  def update_loot
    if params[:commit] =~ /delete/i
      delete_loot(params)
    else
      params.each_key { |k|
        if k =~ /^loot([[:digit:]]+)$/
          loot = Loot.find($1.to_i)
          loot.update_attributes(params[k])
          if loot.save
            flash[:notice] = "Loot records updated."
          else
            flash[:notice] = "Failed to update loot record."
          end 
        end
      }
    end
    expire_fragment("characters/dkp_table")
    redirect_to :action => :edit, :id => params[:raid_id]
  end

  private
  helper_method(:still_got_time_to_signup_for_raid?)
  def still_got_time_to_signup_for_raid?(raid)
    now = Time.now.to_i
    raid_time = raid.date.to_i
    last_signup_time = raid_time - (60 * 60 * 0.5)
    return (now < last_signup_time)
  end

  def delete_loot(params)
    loot_was_deleted = false
    params.each_key { |k|
      if k =~ /^deleteloot([[:digit:]]+)$/
        Loot.destroy($1.to_i)
        loot_was_deleted = true
      end
    }
    if loot_was_deleted
      flash[:notice] = "Loot deleted."
    else
      flash[:notice] = "Select loot to delete."
    end
  end

  def raid_week(date)
    weekday = date.wday()
    offset = nil
    if weekday < 4
      offset = -weekday - 4
    else
      offset = 3 - weekday
    end

    # include the first day of the next week too, so we can ask for raids
    # between the last day of this week and the first day of next week.
    time_in_seconds = Time.local(date.year, date.mon, date.day, 3).to_i
    day_in_seconds = 60 * 60 * 24
    offset_in_seconds = day_in_seconds * offset
    (0..7).collect { |i|
      Time.at(time_in_seconds + offset_in_seconds + (i * day_in_seconds))
    }
  end

end
